#region Microsoft Public License
/*
 * (c) Copyright Chenjun Wu. http://utablesdk.codeplex.com
 * 
 * This source is subject to the Microsoft Public License (Ms-PL).
 * Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
 * All other rights reserved.
 */
#endregion

using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace UTable.Objects
{
    /// <summary>
    /// the abstract representation for an object
    /// Layout Properties: the object is located by Bound Size, Position, Orientation, Scale, Z Index in order.
    /// </summary>
    public interface IObject: IVisualNode
    {

        #region Layout Properties

        /// <summary>
        /// Gets or sets minimum width of the object
        /// </summary>
        double MinWidth { get; set; }

        /// <summary>
        /// Gets or sets minimum height of the object
        /// </summary>
        double MinHeight { get; set; }

        /// <summary>
        /// Gets or sets maximum width of the object
        /// </summary>
        double MaxWidth { get; set; }

        /// <summary>
        /// Gets or sets maximum height of the object
        /// </summary>
        double MaxHeight { get; set; }

        /// <summary>
        /// Gets or sets the position of this object relative to its parent container
        /// position is measured by the point (0, 0) of this object
        /// </summary>
        Point Position { get; set; }

        /// <summary>
        /// Gets or sets orientation relative to the parent container
        /// the orientation center is located at the point RotateCenter
        /// </summary>
        double Orientation { get; set; }

        /// <summary>
        /// the center for rotating
        /// </summary>
        Point RotateCenter { get; set; }

        /// <summary>
        /// Gets or sets size scale relative to the parent container
        /// the scale center is located at the point ScaleCenter of this object
        /// </summary>
        double ScaleX { get; set; }

        /// <summary>
        /// Gets or sets size scale relative to the parent container
        /// the scale center is located at the point ScaleCenter of this object
        /// </summary>
        double ScaleY { get; set; }

        /// <summary>
        /// Gets or sets the center for scaling
        /// </summary>
        Point ScaleCenter { get; set; }

        /// <summary>
        /// Gets or sets the Z Index relative to this object's parent container
        /// object with the higher z index will be put topper
        /// </summary>
        int ZIndex { get; set; }

        #endregion

        /// <summary>
        /// Gets the collection of objects for which this object is the owner
        /// </summary>
        ReadOnlyCollection<IObject> OwnedObjects { get; }

        /// <summary>
        /// Gets or sets the UTable.Objects.IObject which owns this object
        /// </summary>
        IObject Owner { get; set; }

        /// <summary>
        /// Gets or sets the operating state of this object (not enabled now)
        /// The operating state can be Viewing, editing and automatic
        /// </summary>
        ObjectOperatingState OperatingState { get; set; }

        /// <summary>
        /// Gets or sets the layout state of this object (not enabled now)
        /// The Layout State can be maximized or normal
        /// </summary>
        ObjectLayoutState LayoutState { get; set; }

        /// <summary>
        /// Gets or sets the value that indicate whether this object can hold other UTable.Objects.IObject
        /// </summary>
        bool CanHoldObjects { get; set; }

        /// <summary>
        /// Gets or sets the value that indicate whether this object can invoke LayoutChanged event
        /// </summary>
        bool NotifyLayoutChangeEnabled { get; set; }

        /// <summary>
        /// Gets the type of this object
        /// </summary>
        Type ObjectType { get; }

        #region Methods
        /// <summary>
        /// Send Message to this object
        /// </summary>
        /// <param name="message">the message</param>
        void SendMessage(object message);

		/// <summary>
		/// Query the data from this object asynchronously
		/// </summary>
		/// <param name="dataFlag">the flag that marks the data needed</param>
		void QueryData(object dataFlag, QueryDataCallback callback);

		/// <summary>
		/// Query the data from this object synchronously
		/// </summary>
		/// <param name="dataFlag">the flag that marks the data needed</param>
		/// <returns>the data needed</returns>
		object QueryData(object dataFlag);

        /// <summary>
        /// Translate the point in this object's coordinate system to the relativeTo object's coordinate system
        /// </summary>
        /// <param name="point">The Point to be translated</param>
        /// <param name="relativeTo">the relative object</param>
        /// <returns>the point translated</returns>
        Point TranslatePoint(Point point, IObject relativeTo);

        /// <summary>
        /// Close this object
        /// </summary>
        void Close();

        #endregion

        // void BeginAnimation(ObjectAnimationArgs args, ObjectAnimationCompletedHandler completedCallback);

        #region Events

        /// <summary>
        /// Occurs when the layout property of this object changed
        /// </summary>
        event ObjectLayoutChangedEventHandler LayoutChanged;

        // event NotifyOwnedObjectsChangedEventHandler OwnedObjectsChanged;

        /// <summary>
        /// Occurs when the layout state of this object changed
        /// </summary>
        event EventHandler LayoutStateChanged;

        /// <summary>
        /// Occurs when the operating state of this object changed
        /// </summary>
        event EventHandler OperatingStateChanged;

        /// <summary>
        /// Occurs when the object loaded
        /// </summary>
        event EventHandler ObjectLoaded;

        /// <summary>
        /// Occurs when the object is closed
        /// </summary>
        event EventHandler Closed;

        /// <summary>
        /// Occurs when the owner of this object changed
        /// </summary>
        event EventHandler OwnerChanged;

        /// <summary>
        /// Occurs when the children of this object changed
        /// It can be a new child is added, or a child is removed
        /// </summary>
        event ObjectChildrenChangedEventHandler ChildrenChanged;

		/// <summary>
		/// Occurs when this object begins to be dragged
		/// </summary>
		event ObjectDragEventHandler DragStarted;

		/// <summary>
		/// Occurs when this object ends to be dragged
		/// </summary>
		event ObjectDragEventHandler DragEnded;

        #endregion
    }

	public delegate void QueryDataCallback(IObject from, object dataFlag, object data);

	public delegate void SendMessageHandler(object message);

	public delegate void QueryDataAsyncHandler(object dataFlag, QueryDataCallback callback);

	public delegate object QueryDataSyncHandler(object dataFlag);

}
